package com.acme.bankapp.service.bank;

import java.io.*;
import java.util.*;

import com.acme.bankapp.domain.bank.*;
import com.acme.bankapp.domain.exception.*;

/**
 * Class provides bank data loader service functionality
 * @author alex
 */
public class BankDataLoaderService {
	private static String feed_path = "src\\main\\resources\\feed.txt";
	private static String data_path = "src\\main\\resources\\data.txt";
	
	/**
	 * @param bank the bank
	 */
	public static void loadFeed(Bank bank) {
		try (BufferedReader reader = new BufferedReader(new FileReader(feed_path))) {
			String line;
			while ((line = reader.readLine()) != null) {
				Client client = BankDataLoaderService.parseClient(BankDataLoaderService.parseLine(line));
				try {
					BankService.addClient(bank, client);
				} catch (ClientExistsException | IllegalArgumentException e) {
					System.out.println("Err: Client add error!");
				}
			}
		} catch (IOException e) {
			System.out.println("Err: File read error!");
		}
	}
	
	/**
	 * @param line the line
	 * @return the client data
	 */
	public static Map<String, String> parseLine(String line) {
		Map<String, String> clientData = new HashMap<>();
		for (String expression: line.split(";")) {
			String[] tempData = expression.split("=");
			clientData.put(tempData[0], tempData[1]);
		}
		return clientData;
	}
	
	/**
	 * @param clientData the client data
	 * @return the client
	 */
	public static Client parseClient(Map<String, String> clientData) {
		double balance = Double.parseDouble(clientData.get("balance"));
		double overdraft = Double.parseDouble(clientData.get("overdraft"));
		
		Gender gender;
		if (clientData.get("gender").equals("f")) {
			gender = Gender.FEMALE;
		} else {
			gender = Gender.MALE;
		}
		
		Account account;
		if (clientData.get("accounttype").equals("c")) {
			account = new CheckingAccount(balance, overdraft);
		} else {
			account = new SavingAccount(balance);
		}
		
		return new Client(clientData.get("name"), gender, account);
	}
	
	/**
	 * @param bank the bank
	 */
	public static void loadBank(Bank bank) {
		try (ObjectInputStream stream = new ObjectInputStream(new FileInputStream(data_path))) {
			bank = (Bank) stream.readObject();
		} catch (IOException e) {
			System.out.println("Err: File read error!");
		} catch (ClassNotFoundException e) {
			System.out.println("Err: Class not found!");
		} catch (ClassCastException e) {
			System.out.println("Err: Class cast exception!");
		}
	}
	
	/**
	 * @param bank the bank
	 */
	public static void saveBank(Bank bank) {
		try (ObjectOutputStream stream = new ObjectOutputStream(new FileOutputStream(data_path))) {
			stream.writeObject(bank);
		} catch (IOException e) {
			System.out.println("Err: File write error!");
		}
	}
}
